
#include "c_world.h"
#include "init.h"

#include "coid/comm/binstream/filestream.h"
#include "coid/comm/metastream/metastream.h"



#define YOFFS   (TWpx/4)

////////////////////////////////////////////////////////////////////////////////
opcd C_World::init()
{
    //read the client conf
    //load_profile();

    ::memset( _manpos, 0, sizeof(_manpos) );
    ::memset( _bombpos, 0, sizeof(_bombpos) );

    TexImage tmp;

    opcd e=0;
/*
    tmp.alpha_to_colorkey( 0x00000008, 0 );
    _img_pwups.create_from( tmp, TARGET_BPP, false );
    _img_pwups.set_colorkey( true, 0x00000008 );
*/

    e = _img_shadow.readTGA("data\\shadow.tga");
    if(e)  return e;
    _img_shadow.flip_to_alpha( 0, true, 224 );
/*
    _img_shadow.create_from( tmp, TARGET_BPP, false );
    _img_shadow.set_colorkey( true, 0x00ffffff );
    _img_shadow.set_alpha( true, 128 );
*/

    //if(!e)  e = load_fire();
    if(!e)  e = load_anim();

    if(!e)  e = assemble_images();
    if(e)  return e;

    e = tmp.readTGA("data\\mpwup.tga");
    if(e)  return e;

    _img_pwups.create_from_template( tmp, TARGET_BPP, TexImage::sw_surfaces );
    _img_pwups.draw_all_tiles( _imgsample_back );
    _img_pwups.draw( tmp, 0, 0, TexImage::DRAWMODE_ALPHA_BLIT );


    //_img_viewman.readTGA("data\\man.tga", 0x00ff7f00, 0x00ffffff );
    //_img_viewman.readTGA("data\\man.tga", 0x00ffffff, 0x00ff7f00 );
    //_img_viewman.readTGA("data\\man.tga", 0x00ff7f7f, 0x003f3fff );
    //e = _img_viewman.readTGA("data\\man.tga", 0x00000000, 0x00ffffff );

    return e;
}

////////////////////////////////////////////////////////////////////////////////
void C_World::draw( const moving* me )
{
    //checks if needed to
    //colorize_players();

    if( _atile.size() == 0 )  return;

    const TILE* pt = _atile.ptr() + (YTILES-1)*XTILES;

    uint fr = Gactive_controller->get_current_stateid() >> 1;

    //tiles
    int y = -YOFFS;
    {for( uint i=0; i<=YTILES; ++i, pt-=XTILES, y+=TWpx )
    {
        if( i == YTILES )
            pt = _atile.ptr() + (YTILES-1)*XTILES;

        int x = -TWpx/2;
        for( uint j=0; ; ++j, x+=TWpx )
        {
            const TILE* ptt = j == XTILES ? pt : pt+j;

            //SCREEN.draw( TexImage(_img_back, (j&1)*TWpx, (i&1)*TWpx, TWpx, TWpx), x, y );

            if( ptt->type == TILE::HARD )
            {
                SCREEN.draw( TexImage(_img_wall,0,0,TWpx,TWpx), x, y, TexImage::DRAWMODE_BLIT );
            }
            else if( ptt->type == TILE::SOFT )
            {
                SCREEN.draw( TexImage(_img_wall,0,2*TWpx,TWpx,TWpx), x, y, TexImage::DRAWMODE_BLIT );
            }
            else if( ptt->type == TILE::SOFTBURNING )
            {
                uint fr = 1 + (Gactive_controller->get_current_stateid() >> 3) % 7;

                SCREEN.draw( TexImage(_img_wall,(fr&3)*TWpx,2*TWpx + (fr>>2)*TWpx,TWpx,TWpx), x, y, TexImage::DRAWMODE_BLIT );
            }
            else
            {/*
                SCREEN.draw( TexImage(_img_back, (j&1)*TWpx, (i&1)*TWpx, TWpx, TWpx), x, y );

                if( ptt->vcount || ptt->hcount )
                    draw_flame( SCREEN, ptt, fr, x, y );

                for( uint p=0; p<ptt->_pow.size(); ++p )
                {
                    TexImage si;

                    uchar t = ptt->_pow[p]._type;
                    if( t < POWERUP::LAST_POS )
                    {
                        if(t--)
                            si.set( _img_pwups, (t%4)*TWpx, (3-t/4)*TWpx, TWpx, TWpx );
                    }
                    else if( t == POWERUP::COMBINED )
                        si.set( _img_pwups, TWpx, 0, TWpx, TWpx );
                    else
                        si.set( _img_pwups, 0, 0, TWpx, TWpx );

                    SCREEN.draw( si, x, y, TexImage::DRAWMODE_ALPHAKEY_BLIT );
                }*/
                if( ptt->vcount || ptt->hcount )
                    draw_flame( SCREEN, ptt, fr, x, y );
                else if( ptt->_pow.size() )
                    draw_powerup( SCREEN, ptt, x, y );
                else
                    SCREEN.draw( TexImage(_img_back, (j&1)*TWpx, (i&1)*TWpx, TWpx, TWpx), x, y );
            }

            if( j == XTILES )
                break;
        }
    }}

    _drawbuf.reset();

    for( uint m=0; m<MEN; ++m )
    {
        if( _men[m]->in_world() )
            *_drawbuf.add() = _men[m];

        const rsp_dynarray<bomb,true>& ba = _men[m]->get_bombs();
        for( uint b=0; b<ba.size(); ++b )
            if( ba[b]->in_world() )
                *_drawbuf.add() = ba[b];
    }

    _moving_sorter._me = me;
    std::sort( _drawbuf.begin(), _drawbuf.end(), _moving_sorter );
    
    for( uint i=0; i<_drawbuf.size(); ++i )
    {
        const moving& m = *_drawbuf[i];
        draw_moving(m);
        if( m.is_man() )
        {
            uint k = m.get_man();
            _olddir[k] = m.get_direction();
            _oldflg[k] = m._flags;
        }
    }

    if( gs.counter > 0  &&  gs.state == GS_ROUND )
    {
        uint nsec = (gs.counter * _Timer.get_period_usec()) / 1000000;

        if(nsec)
        {
            uint min = nsec/60;
            uint sec = nsec%60;
            charstr tm;
            tm.append_num( 10, min );
            tm.append(':');
            tm.append_num( 10, sec, 2, charstr::ALIGN_NUM_FILL_WITH_ZEROS );

            FONT.print( SCREEN, GWS.width - (3*TWpx)/2, 0, tm );
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
void C_World::draw_moving( const moving& m )
{
    int x = get_coord( m._xyzd0.x );
    int y = get_coord( m._xyzd0.y ) + YOFFS + TWpx/2;
    int z = get_coord( m._xyzd0.z );

    x -= TWpx;
    y = GWS.height - y;

    if( m.is_man() )
    {
        static uchar animfr[] = {1, 2, 3, 4, 5, 6}; // { 1, 2, 1, 3, 4, 3 };

        //man
        man& mx = (man&)m;

        uint odir = _olddir[ m.get_man() ];
        uint ndir = m.get_direction();

        uint viewdir = m.get_lookdir();
        uint fr = viewdir;
        bool bhalflift = false;
//        bool adjphase = false;

        if( m.get_handsup() )
            fr += 4*(NMANANIM/2);
/*        {
            ushort flg = _oldflg[ m.get_man() ];
            if( (flg & moving::fHANDSUP) == 0 )     //wasn't up before, show half lifted
                fr = 4*(NMANANIM+2), bhalflift=true;
            else
                fr = 4*(NMANANIM/2), adjphase=true;
        }
        else
            adjphase=true;
        fr += viewdir;
*/

        if( !m.is_stopped() )
        {
            uint afr = ((Gactive_controller->get_current_stateid() * m._speed ) / 80 ) % sizeof(animfr);
            fr += 4*(1+animfr[afr]);

            viewdir += 4;
        }

        x += _manpos[fr].x;
        y += _manpos[fr].y;

        y -= 8;
        if( ndir & dir::fNORTH )  y -= 8;

        int sy = y + TWpx/6;
        int sx = x;
        y -= z/2;

        //man is 96x96, adjust
        x -= (96-TWpx)/2;
        y -= 96-TWpx;

/*
        y -= 5;
        int sx = x;
        int sy = y + TWpx/6;

        x -= TWpx/2;
        y -= z + TWpx;
*/

        if( mx.is_dying() )
        {
            int ff = mx.get_ticks()/5 - 2;
            ff = MAX_DEATH_ANIM_FRAMES - 1 - ff;
            if( ff >= 0 )
            {
                if( ff >= MAX_DEATH_ANIM_FRAMES )
                    ff = MAX_DEATH_ANIM_FRAMES - 1;

                SCREEN.draw_repeat( _img_shadow, sx, sy, TexImage::DRAWMODE_SHADOW );
            
                SCREEN.draw_colorize_repeat( _aspr_explode._array[ff], 0,
                    mx.get_colorpri(), mx.get_colorsec(), x, y );
            }
            else
            {
                SCREEN.draw_repeat( _img_shadow, sx, sy, TexImage::DRAWMODE_SHADOW );

                SCREEN.draw_colorize_repeat( _spr_man._array[0], 0,
                    mx.get_colorpri(), mx.get_colorsec(), x, y );
            }
        }
        else
        {
/*
            y -= 3;
            //swne
            int ifr = m.get_lookdir();
            fr += ifr & 3;
            if( dire & dir::fWEST )         fr += 1;
            else if( dire & dir::fNORTH )   fr += 2, y-=8, sy-=8;
            else if( dire & dir::fEAST )    fr += 3;
            else                            y -= 1;
*/
            bool illdraw=true;
            if( mx.is_ill() )
                illdraw = ((Gactive_controller->get_current_stateid() * rnd_int::get_multiplier()) & 15) != 0;

            if(illdraw)
            {
                if( m.get_handsup() )
                {
                    //swne
                    static int dx[] = { -4, -24, 4, 24,
                                        -4, -24, 4, 24 };
                                        //-4, -32, 4, 32 };
                    static int dy[] = { 6, -14, -24, -14,
                                        6, -14, -24, -14 };
                                        //0+32, -18+32, -24+32, -18+32 };
                    int hx = sx + dx[viewdir];
                    int hy = y + dy[viewdir];

                    if( ((man&)m).trigger_count() > 0 )
                        SCREEN.draw_colorize_repeat( _spr_bomb._array[8], 0,
                        mx.get_colorpri(), mx.get_colorsec(), hx, hy );
                    else
                        SCREEN.draw_colorize_repeat( _spr_bomb._array[0], 0,
                        mx.get_colorpri(), mx.get_colorsec(), hx, hy );
                }

                SCREEN.draw_repeat( _img_shadow, sx, sy, TexImage::DRAWMODE_SHADOW );

                SCREEN.draw_colorize_repeat( _spr_man._array[fr], 0,
                    mx.get_colorpri(), mx.get_colorsec(), x, y );
            }
        }
    }
    else
    {
        //bomb
        uint fr = Gactive_controller->get_current_stateid() / 6;
        fr &= 3;

        bomb& bm = (bomb&)m;
        if( m.get_jelly() )
            fr += 4;
        else if( bm.is_trigger() )
            fr += 8;

        if( bm.get_flame() < 0 )   //burning
        {
            //draw_flames(&bm);
            return;
        }

        //y -= TWpx/4;

        int sy = y + TWpx/6;
        SCREEN.draw_repeat( _img_shadow, x, sy, TexImage::DRAWMODE_SHADOW );

        y -= z/2;

        //if( m.is_tied() )
        //    _img_bombs[p].wdraw_alpha( 0.8f, x, y, x+dx, y+dy, tx, ty, tx+.25, ty+.25 );
        //else
        man& mx = *_men[bm.get_man()];
        SCREEN.draw_colorize_repeat( _spr_bomb._array[fr], 0,
            mx.get_colorpri(), mx.get_colorsec(), x, y );
    }
/*
    //show bounding area
    x = get_coord( m._xyzd0[0] ) - TWpx/2;
    y = GWS.height - (get_coord( m._xyzd0[1] ) + YOFFS);

    uint r = (m._coll->get_radius()*TWpx).whole();
    SCREEN.fill( x - r, y-4, 1, 8, 0x0000ff00 );
    SCREEN.fill( x + r, y-4, 1, 8, 0x0000ff00 );
    SCREEN.fill( x-4, y - r, 8, 1, 0x0000ff00 );
    SCREEN.fill( x-4, y + r, 8, 1, 0x0000ff00 );
    */
}
/*
////////////////////////////////////////////////////////////////////////////////
void C_World::draw_flames( bomb* b )
{
    int x = modx(b->get_tile_x()) * TWpx;
    int y = mody(b->get_tile_y()) * TWpx;
    x -= TWpx/2;
    y += YOFFS + TWpx;

    y = GWS.height - y;

    uint fr = 3 & (Gactive_controller->get_current_stateid() >> 1);

    man& m = _men[b->get_man()];
    uint32 cp = m.get_colorpri();
    uint32 cs = m.get_colorsec();

    SpriteFrame sf;

    //center
    get_flame( sf, 0, 0, fr );
    SCREEN.draw_colorize( sf,
        cp, cs, x, y );


    uchar fls = -b->get_flame() - 1;
    uchar* flsize = b->get_flsize_ptr();

    //x+
    int xx = x + TWpx;
    uchar i,n;
    n = flsize[0] & 0x7f;
    //if( flsize[0] & 0x80 )  --n;
    for( i=1; i<n; ++i )
    {
        get_flame( sf, i==fls ? UMAX : i, 1, fr );
        SCREEN.draw_colorize( sf,
            cp, cs, xx, y );
        xx += TWpx;
    }

    //x-
    xx = x - TWpx;
    n = flsize[1] & 0x7f;
    //if( flsize[1] & 0x80 )  --n;
    for( i=1; i<n; ++i )
    {
        get_flame( sf, i==fls ? UMAX : i, 3, fr );
        SCREEN.draw_colorize( sf,
            cp, cs, xx, y );
        xx -= TWpx;
    }

    //y+
    float yy = y - TWpx;
    n = flsize[2] & 0x7f;
    //if( flsize[2] & 0x80 )  --n;
    for( i=1; i<n; ++i )
    {
        get_flame( sf, i==fls ? UMAX : i, 2, fr );
        SCREEN.draw_colorize( sf,
            cp, cs, x, yy );
        yy -= TWpx;
    }

    //y-
    yy = y + TWpx;
    n = flsize[3] & 0x7f;
    //if( flsize[3] & 0x80 )  --n;
    for( i=1; i<n; ++i )
    {
        get_flame( sf, i==fls ? UMAX : i, 0, fr );
        SCREEN.draw_colorize( sf,
            cp, cs, x, yy );
        yy += TWpx;
    }
}
*/
